<?php
if (!defined("SMARTY_VIEW_FUNCTIONS_LOADED")) {
	require(dirname(__FILE__) . "/functions.php");
}

/**
 * smarty视图
 *
 * @package if
 * @subpackage module.smartyview
 * @since 1.0
 */
class ISmartyView extends ITplView {	
	private $tpl;
	private $ext;
	/**
	 * Enter description here...
	 *
	 * @var Smarty
	 */
	private $smarty;
	private $layout;
	
	/**
	 * 构造
	 *
	 * @param string|null $tpl 模板名，默认为和动作对应
	 * @param string|null $ext 扩展名，默认和配置一致
	 * @since 1.0
	 */
	function __construct($tpl = null, $ext = null) {
		$this->tpl = $tpl;
		$this->ext = $ext;
		$this->smarty = &ISmarty::load();
		$this->_loadFunctions();
	}
	
	/**
	 * 模板的名称
	 *
	 * @return string
	 * @since 1.0
	 */
	function name() {
		return "smarty";
	}
	
	/**
	 * 显示分析后的模板内容
	 *
	 * @since 1.0
	 */
	function display() {
		//加入自己的属性
		$this->smarty->IF_VARS = array();
		
		$vars = get_object_vars($this->smarty);
		foreach ($vars as $name=>$value) {
			if ($this->opt($name)) {
				$this->smarty->$name = $this->opt($name);
			}
		}
		
		//选项
		foreach ($this->values() as $key=>$value) {
			$this->smarty->assign($key, $value);
		}
		
		//模板文件
		if (!$this->ext) {
			$this->ext = "tpl";
		}
		if (!$this->tpl) {
			$this->tpl = $this->tpl($this->ext);
		}
		else {
			$this->tpl .= "." . $this->ext;
		}
		$this->smarty->IF_VARS["tpl"] = "file:" . $this->opt("template_dir") . "/" . $this->tpl;
		
		//layout
		if (strstr($this->tpl, "#")) {//v1.0.3 把 : 号改成 # 号
			list($this->layout, $this->tpl) = explode("#", $this->tpl, 2);
		}
		
		//自动创建编译目录
		$compileDir = new IFile($this->opt("compile_dir"));
		if (!$compileDir->exists()) {
			@$compileDir->mkdirs();
		}
		
		if (!$compileDir->canWrite()) {
			$this->_log("smarty template compilation dir '" . $compileDir->path() . "' must be writeable", ILog::LOG_FATAL);
		}
		
		//显示模板
		$filename = if_is_absolute_path($this->tpl) ? $this->tpl : $this->opt("template_dir") . "/" . $this->tpl;
		if (is_file($filename)) {
			$this->_procLayout($filename);//处理layout
			$this->smarty->display("file:" . str_replace("/", DIRECTORY_SEPARATOR, $filename));
		}
	}
	
	/**
	 * 加载Smarty功能
	 *
	 * @return Smarty
	 * @since 1.0
	 */
	private function _loadFunctions() {
		
		/**$this->_registerFunctions(array(
			//常量
			"__URI__" => "if_smarty__URI__",
			"__BASE__" => "if_smarty__BASE__",
			"__ROUTER__" => "if_smarty__ROUTER__",
			"__CONTROLLER__" => "if_smarty__CONTROLLER__",
			"__ACTION__" => "if_smarty__ACTION__",
			
			//控制器支持
			"if_errors" => "if_smarty_errors",
			"if_url" => "if_smarty_url",
			"if_x" => "if_smarty_x",
			"if_o" => "if_smarty_o",
			"if_m" => "if_smarty_m",
			
			//HTML支持
			"if_html_options" => "if_smarty_html_options",
			"if_html_checkboxes" => "if_smarty_html_checkboxes",
			"if_radios" => "if_smarty_html_radios",
			"if_options" => "if_smarty_html_options",
			"if_checkboxes" => "if_smarty_html_checkboxes",
			"if_options_range" => "if_smarty_options_range",
			"if_options_years" => "if_smarty_options_years",
			"if_options_months" => "if_smarty_options_months",
			"if_options_months_full" => "if_smarty_options_months_full",
			"if_options_months_short" => "if_smarty_options_months_short",
			"if_options_days" => "if_smarty_options_days",
			"if_options_countries" => "if_smarty_options_countries",
		));**/
		
		//layout
		//$this->smarty->register_prefilter("if_smarty_prefilter_layout");
		$this->smarty->register_prefilter("if_smarty_prefilter_ui");
		$this->smarty->register_outputfilter("ui_smarty_outputfilter");
		/**$this->_registerFunctions(array(
			"if_layout_check" => "if_smarty_check_layout")
		);**/
		
		//逻辑支持
		$this->smarty->register_block("if_dynamic", "if_smarty_block_dynamic", false);
	}
	
	private function _registerFunctions(array $mapping) {
		foreach ($mapping as $function => $impl) {
			$this->smarty->register_function($function, $impl);
		}
	}
	
	private function _procLayout($filename) {
		//处理layout
		$controllerAttrs = $this->controller()->attrs();
		$action = $this->controller()->action()->name();
		$layout = "_layout." . $this->ext;
		if ($this->layout) {
			$layout = $this->layout . "." . $this->ext;
		}
		else if (isset($controllerAttrs["_layout"])) {
			$opt = $controllerAttrs["_layout"];
			if (is_string($opt)) {
				$layout = $opt . "." . $this->ext;
			}
			else if (is_array($opt) && isset($opt["only"])) {
				if (!is_array($opt["only"])) {
					$opt["only"] = explode(",", preg_replace("/\s+/", "", $opt["only"]));
				}
				if (!in_array($action, $opt["only"])) {
					$layout = null;
				}
			}
			else if (is_array($opt) && isset($opt["except"])) {
				if (!is_array($opt["except"])) {
					$opt["except"] = explode(",", preg_replace("/\s+/", "", $opt["except"]));
				}
				if (in_array($action, $opt["except"])) {
					$layout = null;
				}
			}
		}

		if (!is_null($layout)) {
			$dir = dirname($filename);
			$layout = $dir . "/" . $layout;
			$this->smarty->IF_VARS["layout"] = $layout;
		}
	}
	
	/**
	 * 重新分析smarty函数传递的参数，让其支持多级参数
	 * 
	 * 如 
	 * - a.b.c=d
	 * 表示
	 * - $params["a"]["b"]["c"] = "d";
	 *
	 * @param array $params 原有的参数
	 * @return array
	 */
	static function parseSmartyParams($params) {
		$newParams = array();
		foreach ($params as $param => $value) {
			$newParams = if_array_set($newParams, $param, $value);
		}
		return $newParams;
	}
}

?>